package com.chenshanji.lease.web.app.service.impl;

import com.chenshanji.lease.common.obs.ObsProperties;
import com.chenshanji.lease.web.app.service.FileService;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.CreateBucketRequest;
import com.obs.services.model.StorageClassEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private ObsProperties properties;

    @Autowired
    private ObsClient obsClient;

    @Override
    public String upload(MultipartFile file) throws IOException {

        String ak = properties.getAk();
        String sk = properties.getSk();
        String bucketName = properties.getBucketName();
        String endPoint = properties.getEndpoint();
        String location = properties.getLocation();
        String policy = createBucketPolicyConfig(bucketName);

        CreateBucketRequest request = new CreateBucketRequest();
        //桶区域位置
        request.setLocation(location);
        //桶名称
        request.setBucketName(bucketName);
        //桶的存储类别
        request.setBucketStorageClass(StorageClassEnum.WARM);

        //创建ObsCline实例
        new ObsClient(ak, sk, endPoint);

        // 校验endpoint格式
        if (endPoint.startsWith("http")) {
            throw new IllegalArgumentException("OBS endpoint配置错误：不能包含协议头，请检查配置项 [当前值：" + endPoint + "]");
        }
        try {
            // 检查桶是否存在
            boolean exists = obsClient.headBucket(bucketName);

            // 如果桶不存在，则创建桶
            if (!exists) {
                System.out.println('\n'+"桶不存在！"+'\n'+"创建桶"+'\n');
                // 创建桶
                System.out.println(request);
                obsClient.createBucket(request);
                // 设置桶策略
                System.out.println(policy);
                obsClient.setBucketPolicy(bucketName, policy);
            }
            System.out.println("桶存在！");
            // 生成文件名
            String filename = new SimpleDateFormat("yyyyMMdd").format(new Date())
                    + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();

            System.out.println("上传的文件名："+filename);

            // 上传文件
            obsClient.putObject(bucketName, filename, file.getInputStream());
            System.out.println("文件上传成功！");
            // 返回访问URL
            return String.format("https://%s.%s/%s",
                    bucketName,
                    endPoint,
                    filename);

        } catch (ObsException e) {
            throw new IOException("OBS操作失败: " + e.getErrorMessage(), e);
        }
    }

    private String createBucketPolicyConfig(String bucketName) {
        return """
                {
                    "Statement": [
                        {
                            "Sid": "lease",
                            "Effect": "Allow",
                            "Principal": {
                                "ID": [
                                    "*"
                                ]
                            },
                            "Action": [
                                "ListBucket",
                                "ListBucketVersions",
                                "HeadBucket",
                                "GetBucketLocation",
                                "PutObject",
                                "GetObject",
                                "ModifyObjectMetaData",
                                "ListBucketMultipartUploads",
                                "ListMultipartUploadParts",
                                "AbortMultipartUpload",
                                "RestoreObject",
                                "GetObjectVersion",
                                "PutObjectAcl",
                                "GetObjectVersionAcl",
                                "GetObjectAcl"
                            ],
                            "Resource": [
                                "lease",
                                "lease/*"
                            ]
                        }
                    ]
                }
                """.formatted(bucketName,bucketName);
    }
}
